package cn.org.xwb.bookmall.admin.controller;

import cn.org.xwb.bookmall.admin.annotation.IsLoginParam;
import cn.org.xwb.bookmall.model.constant.AccountConst;
import cn.org.xwb.bookmall.model.po.AllowMail;
import cn.org.xwb.bookmall.model.po.Bg;
import cn.org.xwb.bookmall.model.service.impl.BgServiceImpl;
import cn.org.xwb.bookmall.model.utils.BookRedisUtil;
import cn.org.xwb.common.encrypt.annotation.des.DesEn;
import cn.org.xwb.common.encrypt.annotation.rsa.RsaDe;
import cn.org.xwb.common.encrypt.annotation.rsa.RsaDeParam;
import cn.org.xwb.common.encrypt.constant.EncryptConstant;
import cn.org.xwb.common.error.annotation.ServerErrorCatch;
import cn.org.xwb.common.model.vo.RespResult;
import cn.org.xwb.common.page.dto.PageResult;
import cn.org.xwb.common.page.utils.PageUtil;
import cn.org.xwb.common.redis.utils.RedisUtil;
import cn.org.xwb.common.valid.annotation.nu.NotNull;
import cn.org.xwb.common.valid.annotation.nu.NotNullParam;
import cn.org.xwb.common.valid.annotation.str.StrNotNull;
import cn.org.xwb.common.valid.annotation.str.StrNotNullParam;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/bg")
public class AdminBgController {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private BookRedisUtil bookRedisUtil;

    @Autowired
    private BgServiceImpl bgService;

    private String getKeyAllowMails() {
        return bookRedisUtil.getRedisKeyAdmin("bg", "");
    }

    private List<Bg> findAndCacheAll() {
        LambdaQueryWrapper<Bg> wrapper = new LambdaQueryWrapper<>();
        wrapper.isNotNull(Bg::getImgUrl);
        List<Bg> bgs = bgService.getBaseMapper().selectList(wrapper);
        // 缓存
        Boolean res = redisUtil.setList(getKeyAllowMails(), bgs);
        if (!res) return null;
        return bgs;
    }

    private List<Bg> findAllFromCache() {
        // 从缓存中查询
        List<Bg> bgs = (List<Bg>) redisUtil.get(getKeyAllowMails());
        // 缓存中不存在，从数据库中查询，并缓存
        if (Objects.isNull(bgs)) bgs = findAndCacheAll();
        // 发生异常
        if (Objects.isNull(bgs)) return null;
        // 获取成功
        return bgs;
    }

    @GetMapping("/page")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @IsLoginParam
    @DesEn
    public RespResult<Object> getBgPage(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam(EncryptConstant.DES_KEY_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String desKey,
            @RequestParam("current")
            Integer current,
            @RequestParam("pageSize")
            Integer pageSize
    ) {
        // 获取全部的数据
        List<Bg> bgs = findAllFromCache();
        PageResult<List<Bg>> pageResult = new PageResult<>();
        if (Objects.isNull(bgs)) {
            pageResult.setCurrent(0);
            pageResult.setPageSize(0);
            pageResult.setSize(0);
            pageResult.setPageCnt(0);
            pageResult.setData(new ArrayList<>());
        } else {
            // 页数
            Integer pageCnt = PageUtil.getPageCnt(bgs.size(), pageSize);
            // 分页数据
            bgs = ((List<Bg>) PageUtil.getPageData(bgs, current, pageSize));
            pageResult = new PageResult<List<Bg>>(current, pageSize, bgs.size(), pageCnt, bgs);
        }
        return RespResult.success("获取背景图片列表成功", pageResult);
    }

    @PostMapping("/add")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @IsLoginParam
    @Transactional
    public RespResult<Object> addBg(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam("imgUrl") @StrNotNullParam @RsaDeParam
            String imgUrl
    ) {
        LambdaQueryWrapper<Bg> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Bg::getImgUrl, imgUrl);
        Bg one = bgService.getOne(wrapper);
        if (Objects.nonNull(one)) {
            return RespResult.fail("请勿重复添加");
        }
        Bg bg = new Bg();
        bg.setImgUrl(imgUrl);
        int res = bgService.getBaseMapper().insert(bg);
        if (res < 1) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("添加失败");
        }
        List<Bg> bgs = findAndCacheAll();
        if (Objects.isNull(bgs)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("添加失败");
        }
        return RespResult.success("添加成功");
    }

    @PostMapping("/del")
    @ServerErrorCatch
    @StrNotNull
    @NotNull
    @RsaDe
    @IsLoginParam
    @Transactional
    public RespResult<Object> delBg(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @NotNullParam
            Long id
    ) {
        boolean res = bgService.removeById(id);
        if (!res) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("删除失败");
        }
        List<Bg> bgs = findAndCacheAll();
        if (Objects.isNull(bgs)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("删除失败");
        }
        return RespResult.success("删除成功");
    }

}
